/* 
 * File:   Fuctions.cpp
 * Author: frank
 *
 * Created on 2013年10月23日, 下午8:57
 */

#include"FileMng.h"


////////////////////////////////////////////////////////////////////////
//
//								功能模块化函数
//
///////////////////////////////////////////////////////////////////////

//在空闲块表中得到一个空块，并返回(块号)
int getVacSect(int vNum)
{
	int i,n,sect;
	short num;
	char *tmp;
	num=openFileMemo[vNum].sectMemo[0][1];
	VacantTable *vTable;
	vTable=(VacantTable*)strMemo[num];
	n=vTable->sectNum;
	if(n==0)
		return FAIL;
	sect=vTable->start[0];
	
	vTable->start[0]=sect+1;
	vTable->len[0]=vTable->len[0]-1;
	if(vTable->len[0]==0){
		n--;
		vTable->sectNum=n;
		for(i=0;i<n;i++){
			vTable->start[i]=vTable->start[i+1];
			vTable->len[i]=vTable->len[i+1];
		}
	}
	tmp=(char*)vTable;
	strcpy(strMemo[num],tmp);

	//将硬盘上的这个块初始化
	writeBack("-------",sect);
	openFileMemo[vNum].mod=1;

	return sect;
}

//把sect块加入空闲块表中（1=succ 0=fail）
void delSect(int vNum,short sect)
{
	int i,j,n;
	short st;
	char *tmp;
	short num;

	num=openFileMemo[vNum].sectMemo[0][1];
	VacantTable *vTable;
	vTable=(VacantTable*)strMemo[num];
	n=vTable->sectNum;
	for(i=0;i<n;i++){
		st=vTable->start[i];
		if(st>sect){
			if(i==0){  //此块在第一个空闲块前
				if(st-sect==1){  //此块后是空闲块
					vTable->start[i]=vTable->start[i]-1;
					vTable->len[i]=vTable->len[i]+1;
				}
				else{  //前后都不是空闲块
					for(j=n;j>0;j--){
						vTable->start[j]=vTable->start[j-1];
						vTable->len[j]=vTable->len[j-1];
					}
					vTable->start[0]=sect;
					vTable->len[0]=1;
					n++;
					vTable->sectNum=n;
				}
			}
			else{  //此块前有其他空闲块
				if(vTable->start[i-1]+vTable->len[i-1]==sect){  //此块前是空闲块
					if(st-sect==1){  //此块前后是空闲块
						vTable->len[i-1]=vTable->len[i-1]+vTable->len[i]+1;
						n--;
						vTable->sectNum=n;
						for(j=i;j<n;j++){
							vTable->start[j]=vTable->start[j+1];
							vTable->len[j]=vTable->len[j+1];
						}
					}
					else   //此块前是空闲块,后不是
						vTable->len[i-1]=vTable->len[i-1]+1;
				}
				else if(st-sect==1){  //此块后是空闲块,前不是
					vTable->start[i]=vTable->start[i]-1;
					vTable->len[i]=vTable->len[i]+1;
				}
				else{  //前后都不是空闲块
					for(j=n;j>i;j--){
						vTable->start[j]=vTable->start[j-1];
						vTable->len[j]=vTable->len[j-1];
					}
					vTable->start[i]=sect;
					vTable->len[i]=1;
					n++;
					vTable->sectNum=n;
				}
			}	
		break;
		}
	}
	tmp=(char*)vTable;
	strcpy(strMemo[num],tmp);
	openFileMemo[vNum].mod=1;
}


int getHeadNode(HeadIndex *headIndex, char *filename)
{
    int i;
    for(i=0; i<INDEX_MAX; i++){
        if(strcmp(headIndex[i].name,filename)==0) return i;
    }
    printf("File %s does NOT exist!\n",filename);
    return FAIL;
}


//void loadSects(int inode)
//{       
//    HeadIndex *headIndex;
//    int i,j,size;
//    char filename[50];
//    
//    loadHeadIndex(headIndex);
//    headIndex[inode].size;
//    
//    //插入打开文件表并装入内存
//        while(openedSize+headIndex[inode].size>STRMEMO_MAX||openedSum==OPEN_MAX){
//                printf("TOO MANY files have loaded, please unload some of them!\n");
//                printf("Please input the file name to be unloaded:");
//                cin>>filename;
//                unloadSects(filename);
//        }
//        size=headIndex[inode].size;
//        for(i=0;i<OPEN_MAX;i++){
//                if(openFileMemo[i].access==FAIL){
//                        openedSum++;
//                        strcpy(openFileMemo[i].name,headIndex[inode].name);
//                        openFileMemo[i].access=ACCESS;
//                        openFileMemo[i].mod=0;
//                        openFileMemo[i].loadType=loadType;
//                        openFileMemo[i].size=size;
//                        openFileMemo[i].type=headIndex[inode].type;
//                        for(j=0;j<size;j++){
//                                sect=headIndex[inode].sects[j];
//                                memoNum=loadToMemo(sect);  //装入内存
//                                openFileMemo[i].sectMemo[j][0]=sect;
//                                openFileMemo[i].sectMemo[j][1]=memoNum;
//                        }
//                        break;
//
//                }
//        }
//        return i; 
//
//
//
//}
//
//
//void unloadSects(int inode)
//{
//
//
//
//
//
//}
//


//拆分路径，判断是否为拥有者
int isOwner(char *name,char *filename)
{
	int i,m,n;
	n=strlen(filename);
	for(i=1;i<n;i++)
	{
		if(filename[i]=='/')
			break;
		if(filename[i]!=name[i-1])
			return 0;
	}
	m=strlen(name);
	if(m==(i-1))
		return 1;
	else 
		return 0;
}


void replaceContent(char *stream,int openNum,char*name)
{
	char filename[50],*p;
	int i,j;
	short memoNum,size;
	p=stream;
	openFileMemo[openNum].mod=1;

	for(i=0;;i++){
		if(i==openFileMemo[openNum].size){
			while(openedSize==STRMEMO_MAX){
				printf("TOO MANY files have loaded, please unload some of them!\n");
				printf("Please input the file name to be unloaded:");
				cin>>filename;
				unloadFile(filename,name);	
			}
			for(j=0;j<STRMEMO_MAX;j++){
				if(strcmp(strMemo[j],"\0")==0){
					openedSize++;
					openFileMemo[openNum].sectMemo[i][1]=j;
					openFileMemo[openNum].size++;
					break;
				}
			}
		}

		memoNum=openFileMemo[openNum].sectMemo[i][1];
		for(j=0;j<CONTENT_MAX-1;j++){
			if(*p=='\0'){
				strMemo[memoNum][j]='\0';
				size=openFileMemo[openNum].size;
				openFileMemo[openNum].size=i+1;					
				for(i=i+1;i<size;i++){
					memoNum=openFileMemo[openNum].sectMemo[i][1];	
					unloadMemo(memoNum);		
				}
				return;
			}
			strMemo[memoNum][j]=*p;
			p++;
		}
		strMemo[memoNum][j]='\0';
	}	
	
}

void appendContent(char *stream,int openNum,char*name)
{
	char *p,filename[50];
	short memoNum,size;
	int len,i,j,streamLen;

	openFileMemo[openNum].mod=1;
	size=openFileMemo[openNum].size;
	memoNum=openFileMemo[openNum].sectMemo[size-1][1];
	len=strlen(strMemo[memoNum]);

	while(1){
		streamLen=strlen(stream);
		stream[streamLen]='\0';
		if(streamLen+len>=(SECT_MAX-size+1)*CONTENT_MAX){
			cout<<"The content appending is TOO LONG, please input again:\n";
			cin>>stream;
		}
		else
			break;
	}

	p=stream;
	for(i=len;i<CONTENT_MAX-1;i++){
		if(*p=='\0'){
			strMemo[memoNum][i]='\0';
			return;
		}
		strMemo[memoNum][i]=*p;
		p++;
	
	}
	strMemo[memoNum][i]='\0';

	for(i=size;;i++){
		while(openedSize==STRMEMO_MAX){
			printf("TOO MANY files have loaded, please unload some of them!\n");
			printf("Please input the file name to be unloaded:");
			cin>>filename;
			unloadFile(filename,name);	
		}
		for(j=0;j<STRMEMO_MAX;j++){
			if(strcmp(strMemo[j],"\0")==0){
				openedSize++;
				openFileMemo[openNum].sectMemo[i][1]=j;
				openFileMemo[openNum].size++;
				break;
			}
		}

		memoNum=j;
		for(j=0;j<CONTENT_MAX-1;j++){
			if(*p=='\0'){
				strMemo[memoNum][j]='\0';
				openFileMemo[openNum].size=i+1;
				return;
			}
			strMemo[memoNum][j]=*p;
			p++;
		}
		strMemo[memoNum][j]='\0';
	}	

}
        
void addHead(HeadIndex *headIndex,char *filename,short pms,short sect,short type,short size,long modTime)
{
	int i;
	for(i=0;i<INDEX_MAX;i++){
		if(headIndex[i].type==TYPE_NONE){
			strcpy(headIndex[i].name,filename);
			headIndex[i].PMS=pms;
			headIndex[i].sects[0]=sect;
			headIndex[i].type=type;
			headIndex[i].size=size;
			headIndex[i].modTime=modTime;
			headIndex[i].rdCnt=0;
			headIndex[i].wrtCnt=0;
			break;
		}
	}
}

void delFileInDir(int dirOpenNum, char *file, char *name)
{
	char stream[CONTENT_MAX],line[50];
	char *p,*q;
	int i,j,n,openNum,flag;
	short size,memoNum;

	openNum=dirOpenNum;
	openFileMemo[openNum].mod=1;
	size=openFileMemo[openNum].size;
	strcpy(stream,"\0");
	for(i=0;i<size;i++){
		memoNum=openFileMemo[openNum].sectMemo[i][1];
		strcat(stream,strMemo[memoNum]);
	}
	n=strlen(file);
	p=stream+7;
	while(1){
		for(i=0;;i++){
			if(*(p+i)=='-')
				break;
			else
				line[i]=*(p+i);
		}
		q=p+i+7;
		line[i]='\0';
		flag=0;
		for(i=0;i<n;i++){
			if(line[i]!=file[i]){
				flag=1;
				break;
			}
		}
		if(flag==0){
			if(line[i]=='\t'){
				while(*q!='\0'){
					*p=*q;
					p++;
					q++;
				}
				*p='\0';
				strcpy(strMemo[memoNum],stream);
				
				return;
			}
		}
		p=q;
	}
//	unloadFile(dir,name);
//	return FAIL;
}

void showOpen()
{
	cout<<"\n\n--------FILES IN THE MEMORY---------\n";
	for(int i=0;i<OPEN_MAX;i++){
		if(openFileMemo[i].access!=FAIL)
			cout<<openFileMemo[i].name<<endl;
	}
	cout<<"\n\n------------------------------------\n";
}

